<template>
     <div id="cesiumContainer" style="width: 100%; height: 100vh;"></div> <!-- 定义一个全屏的容器，用于渲染Cesium地图 -->
</template>
<script setup lang="ts">
import * as Cesium from 'cesium'
import { onMounted, ref } from 'vue'
const viewer = ref()
const addOsmBuildingsAsync = async () => {
     try {
          const osmBuildings = await Cesium.createOsmBuildingsAsync();
          viewer.value.scene.primitives.add(osmBuildings);
     } catch (error) {
          console.log(error);
     }

};
onMounted(() => {
     Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxNjkyYWM4Zi1lZGM2LTQxMTQtYWRlMS0wYmRhYmE1ZTcxYWQiLCJpZCI6Mjg4NjI0LCJpYXQiOjE3NDMxNDc2NjZ9.iisBDz51i4kzTVeE79u2w7Mmw_BcVuU5uXnU4O2fL_M'
     addOsmBuildingsAsync()
     viewer.value = new Cesium.Viewer('cesiumContainer', {
          infoBox: false, // 禁用信息框
          navigationHelpButton: false, // 禁用导航帮助按钮
          geocoder: false, // 禁用地理编码器
          homeButton: false, // 禁用主页按钮
          timeline: false, // 禁用时间轴
          animation: false, // 禁用动画控件
          navigationInstructionsInitiallyVisible: false, // 禁用初始导航指令
          scene3DOnly: true, // 强制开启3D交互模式
     })


     const centerLon = 118.03; // 圆心的经度
     const centerLat = 24.485; // 圆心的纬度
     const centerHeight = 100000; // 圆心的高度
     const bigCircleRadius = 20000; // 大圆的半径
     const smallCircleRadius = 5000; // 小圆的半径

     for (let i = 0; i < 8; i++) {
          const angle = (i / 8) * 2 * Math.PI; // 计算每个小圆的角度
          const lon = centerLon + (bigCircleRadius / 111320) * Math.cos(angle); // 计算小圆的经度
          const lat = centerLat + (bigCircleRadius / 111320) * Math.sin(angle); // 计算小圆的纬度

          viewer.value.entities.add({
               name: `Small circle ${i + 1}`, // 小圆的名称
               position: Cesium.Cartesian3.fromDegrees(lon, lat, centerHeight), // 小圆的位置
               ellipse: {
                    semiMinorAxis: smallCircleRadius, // 小圆的短轴半径
                    semiMajorAxis: smallCircleRadius, // 小圆的长轴半径
                    material: Cesium.Color.GREEN.withAlpha(0.5), // 小圆的填充颜色（绿色，50%透明）
                    outline: true, // 是否显示轮廓
                    outlineColor: Cesium.Color.BLACK, // 轮廓颜色（黑色）
               },
          });
     }
     const redball = viewer.value.entities.add({
          name: "Red ball", // 球体的名称
          position: Cesium.Cartesian3.fromDegrees(115.7, 39.9, 100), // 球体的位置
          ellipsoid: {
               radii: new Cesium.Cartesian3(100000.0, 100000.0, 100000.0), // 球体的半径（长轴和短轴）
               material: Cesium.Color.RED.withAlpha(0.5), // 球体的填充颜色（红色，50%透明）
          },
     });

     const startPosition = Cesium.Cartesian3.fromDegrees(110.03, 24.485, 100000);
     const blueEllipsoid = viewer.value.entities.add({
          name: "Blue ellipsoid", // 椭球的名称
          position: Cesium.Cartesian3.fromDegrees(118.03, 24.485, 100000), // 椭球的位置
          ellipsoid: {
               radii: new Cesium.Cartesian3(200000.0, 200000.0, 300000.0), // 椭球的半径（长轴和短轴）
               material: Cesium.Color.BLUE, // 椭球的填充颜色（蓝色）
          },
     });
     // 蓝椭圆 结束的位置
     const endPosition = blueEllipsoid.position.getValue(viewer.value.clock.currentTime);
     // 创建一个采样位置属性对象，用于存储和管理位置的采样数据
     const positionProperty = new Cesium.SampledPositionProperty();
     // 为采样位置属性添加一个起始位置的采样点，时间为当前时间
     positionProperty.addSample(viewer.value.clock.currentTime, startPosition);
     // / 定义动画的总时长，单位为毫秒，这里设置为50000毫秒（即50秒）
     const animationDuration = 50000; // 动画时长，单位毫秒
     // 记录动画开始的时间，使用Date.now()获取当前的时间戳
     const startTime = Date.now();
     // 创建一个回调属性对象，它会根据时间动态计算物体的位置
     const callbackProperty = new Cesium.CallbackProperty(() => {
          // 计算从动画开始到现在所经过的时间
          const elapsed = Date.now() - startTime;
          // 如果经过的时间已经超过或等于动画的总时长
          if (elapsed >= animationDuration) {
               // 直接返回结束位置，意味着动画结束，物体停在结束位置
               return endPosition;
          }
          // 计算当前时间在整个动画时长中所占的比例，范围从0到1
          const ratio = elapsed / animationDuration;
          // 使用线性插值方法计算当前时间物体应该所在的位置
          // 线性插值会根据起始位置、结束位置和比例来确定中间位置
          return Cesium.Cartesian3.lerp(startPosition, endPosition, ratio, new Cesium.Cartesian3());
     }, false);

     const greenEllipsoid = viewer.value.entities.add({
          name: "Green ellipsoid", // 椭球的名称
          position: callbackProperty,// 给绿色小球设定动画
          ellipsoid: {
               radii: new Cesium.Cartesian3(100000.0, 100000.0, 200000.0), // 椭球的半径（长轴和短轴）
               material: Cesium.Color.GREEN, // 椭球的填充颜色（绿色）
          },
     });
     // 天地图影像图层
     const tdtImageryProvider = new Cesium.WebMapTileServiceImageryProvider({
          url: 'http://t0.tianditu.gov.cn/vec_w/wmts?tk=d8da14f1102151eafca8a1d0d8a5919d',
          layer: 'vec',
          style: 'default',
          format: 'tiles',
          tileMatrixSetID: 'w',
          maximumLevel: 18, // 设置最大缩放级别
          minimumLevel: 1, // 设置最小缩放级别
     });
     // 天地图注记图层
     const tdtAnnotationImageryProvider = new Cesium.WebMapTileServiceImageryProvider({
          url: 'http://t0.tianditu.gov.cn/cva_w/wmts?tk=d8da14f1102151eafca8a1d0d8a5919d',
          layer: 'cva',
          style: 'default',
          format: 'tiles',
          tileMatrixSetID: 'w',
          maximumLevel: 18, // 设置最大缩放级别
          minimumLevel: 1, // 设置最小缩放级别
     });
     viewer.value.imageryLayers.addImageryProvider(tdtImageryProvider);
     viewer.value.imageryLayers.addImageryProvider(tdtAnnotationImageryProvider);
     // 设置高质量渲染
     viewer.value.scene.postProcessStages.fxaa.enabled = true;
     var position = Cesium.Cartesian3.fromDegrees(113.3191, 23.109, 2000); // 设置相机位置（经度、纬度、高度）
     //     创建一个点
     const redguangzhou = viewer.value.entities.add({
          name: "Red ball", // 球体的名称
          position: position, // 球体的位置
          ellipsoid: {
               radii: new Cesium.Cartesian3(50.0, 50.0, 50.0), // 球体的半径（长轴和短轴）
               material: Cesium.Color.RED.withAlpha(0.5), // 球体的填充颜色（红色，50%透明）
          },
     });
     try {
          // 构建模型的 URL
          const modelUrl = '/modle/Stork.glb'; // 修正路径

          // 添加 3D 模型
          const airplane = viewer.value.entities.add({
               name: "Airplane",
               position: Cesium.Cartesian3.fromDegrees(113.3191, 23.109, 1500),
               model: {
                    uri: modelUrl,
                    minimumPixelSize:128,
                    scale: 10, // 适当缩放模型
               },
          });
          viewer.value.trackedEntity = airplane;

     } catch (error) {
          console.error('加载模型时出错:', error);
     }
     viewer.value.camera.setView({
          destination: position, // 相机的位置（经度、纬度、高度）
          orientation: {
               heading: Cesium.Math.toRadians(0), // 偏航角，单位为弧度
               pitch: Cesium.Math.toRadians(-45), // 仰俯角，单位为弧度
               roll: Cesium.Math.toRadians(0)  // 翻滚角，单位为弧度
          }
     })
})
</script>